package com.sys.service.impl;

import com.bhudy.base.BaseServiceImpl;
import com.bhudy.base.QueryFilter;
import com.sys.entity.SysRoleMenu;
import com.sys.service.SysRoleMenuService;
import com.sys.utils.ShiroUtils;
import com.sys.utils.Utils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;

/**
 * @Author com.bhudy
 * @Description 角色关联菜单Service实现类
 * @Date 2019-10-30 23:09:37
 */
@Service
@Transactional
public class SysRoleMenuServiceImpl extends BaseServiceImpl<SysRoleMenu, Serializable> implements SysRoleMenuService {

    @Override
    public int createSysRoleMenus(List<SysRoleMenu> sysRoleMenuList, Long roleId) {
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.clear().and("roleId", roleId);
        super.delete(queryFilter);

        return super.insert(sysRoleMenuList);
    }


    @Override
    public List<Map<String, Object>> getTree(Long roleId, int type) {
        try {
            List<Map<String, Object>> sysMenuMapList;
            if (type == 0) {
                //查询所有菜单
                String sql = "select bm.id,bm.name,bm.parent_id parentId,bm.level,bm.path,bm.icon,bm.menu_order menuOrder,bm.type,bm.url,bm.perms,bm.status,brm.get,brm.post,brm.put,brm.delete " +
                        " from sys_menu bm left join (select * from sys_role_menu where role_id = ?) brm on bm.id = brm.menu_id order by menu_order";
                sysMenuMapList = super.findMapList(sql, roleId);
            } else {
                String sql = "select id,name,parent_id parentId,level,path,icon,menu_order menuOrder,type,url,perms from sys_menu where id in (select menu_id from sys_role_menu where role_id in (" +
                        "select role_id from sys_user_role where user_id = ?) and " + super.keyword("get") + " = 1) and type in (1, 3) order by menu_order";
                sysMenuMapList = super.findMapList(sql, ShiroUtils.getUserId());
            }

            //根节点
            List<Map<String, Object>> rootMenuMap = getChild(0L, sysMenuMapList);
            return rootMenuMap;
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 获取子节点
     *
     * @param id             父节点id
     * @param sysMenuMapList 所有菜单列表
     * @return 每个根节点下，所有子菜单列表
     */
    public List<Map<String, Object>> getChild(Long id, List<Map<String, Object>> sysMenuMapList) {
        //子菜单
        List<Map<String, Object>> childMapList = new ArrayList<>();
        for (Map<String, Object> navMap : sysMenuMapList) {
            // 遍历所有节点，将所有菜单的父id与传过来的根节点的id比较
            //相等说明：为该根节点的子节点。
            if (!navMap.containsKey("get")) navMap.put("get", 0);
            if (!navMap.containsKey("post")) navMap.put("post", 0);
            if (!navMap.containsKey("put")) navMap.put("put", 0);
            if (!navMap.containsKey("delete")) navMap.put("delete", 0);
            if (String.valueOf(navMap.get("parentId")) != null && Utils.formatLong(navMap.get("parentId")).equals(id)) {
                childMapList.add(navMap);
            }
        }
        //递归
        for (Map<String, Object> navMap : childMapList) {
            navMap.put("childrenMenuList", getChild(Utils.formatLong(navMap.get("id")), sysMenuMapList));// .setChildrenMenuList();
        }
        Collections.sort(childMapList, order());//排序
        //如果节点下没有子节点，返回一个空List（递归退出）
        if (childMapList.size() == 0) {
            return null;//new ArrayList<SysMenu>();
        }
        return childMapList;
    }

    /**
     * 排序,根据order排序
     */
    public Comparator<Map<String, Object>> order() {
        Comparator<Map<String, Object>> comparator = new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                if (o1.get("menuOrder") != null && !Utils.formatInt(o1.get("menuOrder")).equals(Utils.formatInt(o2.get("menuOrder")))) {
                    return Utils.formatInt(o1.get("menuOrder")) - Utils.formatInt(o2.get("menuOrder"));
                }
                return 0;
            }
        };
        return comparator;
    }

}
